package com.example.musictutor.views;

import java.io.IOException;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.Button;

import com.example.musictutor.domain.Note;

public class KeyButton extends Button implements OnPreparedListener,
		OnCompletionListener {

	private static final int STATE_IDLE = 0;
	private static final int STATE_PLAY = 1;
	private static final int STATE_PAUSE = 2;
	
	private MediaPlayer mMediaPlayer;
	private Note mNote;
	private int state = 0;

	public KeyButton(Context context) {
		super(context);
	}

	public KeyButton(Context context, AttributeSet attr) {
		super(context, attr);
	}

	public KeyButton(Context context, AttributeSet attr, int defStyle) {
		super(context, attr, defStyle);
	}

	private void initializePlayer() {
		if (mMediaPlayer != null) {
			mMediaPlayer.release();
			mMediaPlayer = null;
		}

		mMediaPlayer = new MediaPlayer();
	}

	public void startPlayer() {
		while(state != STATE_IDLE) {
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		initializePlayer();
		Log.d("Key Player", "Initialized...");
		try {
			AssetFileDescriptor afd = getFileDescriptor();

			if (afd != null) {
				mMediaPlayer.setDataSource(afd.getFileDescriptor(),
						afd.getStartOffset(), afd.getDeclaredLength());
				//mMediaPlayer.setOnPreparedListener(this);
				mMediaPlayer.setOnCompletionListener(this);
				//mMediaPlayer.prepareAsync();
				mMediaPlayer.prepare();
				mMediaPlayer.setVolume(0.65f, 0.65f);
				mMediaPlayer.start();
				state = STATE_PLAY;
			}

		} catch (IllegalArgumentException e) {
			Log.e("Player", e.getStackTrace().toString());
		} catch (SecurityException e) {
			Log.e("Player", e.getStackTrace().toString());
		} catch (IllegalStateException e) {
			Log.e("Player", e.getStackTrace().toString());
		} catch (IOException e) {
			Log.e("Player", e.getStackTrace().toString());
		}
	}

	public void stopPlayer() {
		Log.d("Key Player", "Stopped...");
		if (mMediaPlayer != null) {
			
			if(state == STATE_PLAY || state == STATE_PAUSE)
				mMediaPlayer.stop();
			
			mMediaPlayer.release();
			mMediaPlayer = null;
			
			state = STATE_IDLE;
			Log.d("Player States", "----stopped " + mNote.getName());
		}
	}

	private AssetFileDescriptor getFileDescriptor() {
		AssetFileDescriptor afd = null;
		afd = getContext().getResources().openRawResourceFd(mNote.getResourceId());
		return afd;
	}

	@Override
	public void onPrepared(MediaPlayer mp) {
		Log.d("Key Player", "Prepared...");
		
		while(state != STATE_IDLE) {
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		mp.setVolume(0.65f, 0.65f);
		mp.start();
		state = STATE_PLAY;
		Log.d("Player States", "++++Played " + mNote.getName());
	}

	@Override
	public void onCompletion(MediaPlayer mp) {
		Log.d("Key Player", "Completed...");
		if (state == STATE_PLAY || state == STATE_PAUSE)
			mp.stop();

		mp.release();
		mp = null;
		mMediaPlayer = null;
		state = STATE_IDLE;
		
		Log.d("Player States", "----stopped " + mNote.getName());
	}

	public MediaPlayer getmMediaPlayer() {
		return mMediaPlayer;
	}

	public void setmMediaPlayer(MediaPlayer mMediaPlayer) {
		this.mMediaPlayer = mMediaPlayer;
	}

	/*@Override
	public boolean onTouch(View v, MotionEvent event) {
		
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			KeyButton keyButton = (KeyButton) v;
			keyButton.startPlayer();
		}
		
		if (event.getAction() == MotionEvent.ACTION_UP) {
			KeyButton keyButton = (KeyButton) v;
			keyButton.stopPlayer();
		}

		return false;
	}*/

	public Note getNote() {
		return mNote;
	}

	public void setNote(Note note) {
		this.mNote = note;
	}
	
	
}
